package cn.edu.scau.cmi.ema.service;

import cn.edu.scau.cmi.ema.base.CmiPagination;
import cn.edu.scau.cmi.ema.domain.Filler;
import cn.edu.scau.cmi.ema.domain.Fillerhazard;
import cn.edu.scau.cmi.ema.domain.Hazard;
import cn.edu.scau.cmi.ema.service.base.CmiEmaService;
import cn.edu.scau.cmi.ema.util.CmiSqlUtil;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Query;
import java.util.*;
@Service("FillerhazardService")
@Transactional

public class FillerhazardServiceImpl extends CmiEmaService implements FillerhazardService {
	public FillerhazardServiceImpl() {
	}

	@Transactional
	public Fillerhazard saveFillerhazard(Fillerhazard fillerhazard) {

		if (fillerhazard.getId() == null) {
			Filler filler = fillerDAO.findFillerById(fillerhazard.getFiller().getId());
			Hazard hazard = hazardDAO.findHazardById(fillerhazard.getHazard().getId());

			Fillerhazard existingFillerhazard = fillerhazardDAO.findFillerhazardByPhysicalPrimaryKey(filler.getId(),
					hazard.getId(), fillerhazard.getDegree());

			fillerhazard.setFiller(filler);
			fillerhazard.setHazard(hazard);

			if (isEquals(fillerhazard, existingFillerhazard)) {
				return existingFillerhazard;
			}

			fillerhazard = fillerhazardDAO.store(fillerhazard);
			fillerhazardDAO.flush();

		} else {
			Fillerhazard existingFillerhazard = fillerhazardDAO.findFillerhazardByPrimaryKey(fillerhazard.getId());

			fillerhazard = fillerhazardDAO.store(fillerhazard);
			fillerhazardDAO.flush();
		}

		return fillerhazard;
	}

	public void deleteFillerhazard(Fillerhazard fillerhazard) {
		fillerhazardDAO.remove(fillerhazard);
		fillerhazardDAO.flush();
	}

	@Transactional
	public void deleteFillerhazards(Set<Integer> deleteFillerhazardsId) {
		Query query = fillerhazardDAO.createNamedQuery("deleteFillerhazardsById", -1, -1);
		query.setParameter(1, deleteFillerhazardsId);
		query.executeUpdate();
	}

	@Transactional
	public Set<Fillerhazard> loadFillerhazards() {
		return fillerhazardDAO.findAllFillerhazards();

	}

	@Transactional
	public Set<Fillerhazard> loadReferenceFillerhazards(Set<Fillerhazard> fillerhazards) {
		Iterator<Fillerhazard> fillerhazardsIterator = fillerhazards.iterator();
		Set<Fillerhazard> referencedFillerhazards = new HashSet<>();
		while (fillerhazardsIterator.hasNext()) {
			Fillerhazard currentFillerhazard = fillerhazardsIterator.next();

		}
		return referencedFillerhazards;
	}

	public Set<Fillerhazard> loadFillerhazardsByIdSet(Set<Integer> fillerhazardIdSet) {

		Iterator<Integer> fillerhazardIdIterator = fillerhazardIdSet.iterator();
		Set<Fillerhazard> fillerhazardSet = new HashSet<>();
		while (fillerhazardIdIterator.hasNext()) {
			Integer id = fillerhazardIdIterator.next();
			Fillerhazard currentFillerhazard = fillerhazardDAO.findFillerhazardById(id);
			fillerhazardSet.add(currentFillerhazard);
		}
		return fillerhazardSet;
	}

	@Transactional
	public List<Fillerhazard> findAllFillerhazards(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Fillerhazard>(fillerhazardDAO.findAllFillerhazards(startResult, maxRows));
	}

	@Transactional
	public Fillerhazard findFillerhazardByPrimaryKey(Integer id) {
		return fillerhazardDAO.findFillerhazardByPrimaryKey(id);
	}

	@Transactional
	public Integer countFillerhazards() {
		return ((Long) fillerhazardDAO.createQuerySingleResult("select count(o) from Fillerhazard o").getSingleResult())
				.intValue();
	}

	@Transactional
	public Integer countFillerhazards(CmiPagination page) {
		String sql = CmiSqlUtil.createCountHql(page, Fillerhazard.class);
		return ((Long) fillerhazardDAO.createQuerySingleResult(sql).getSingleResult()).intValue();
	}

	/**
	 * search for name with ajax
	 *
	 */
	@Transactional
	public Integer countFillerhazardsByName(String queryName) {
		Query query = fillerhazardDAO.createNamedQuery("countFillerhazardsByName", -1, -1);
		query.setParameter(1, queryName);
		return new Long((long) query.getSingleResult()).intValue();
	}

	@Transactional
	public Integer countFillerhazardsByDetachedCriteria(CmiPagination page) {
		DetachedCriteria detachedCriteria = CmiSqlUtil.createDetachedCriteria(page, Fillerhazard.class);
		Session session = (Session) entityManager.getDelegate();
		detachedCriteria.setProjection(Projections.rowCount());
		return new Long((long) detachedCriteria.getExecutableCriteria(session).uniqueResult()).intValue();
	}

	public Map<String, ?> loadFillerhazardObjectReferencedSet(Fillerhazard fillerhazard) {
		HashMap<String, Object> objectReferencedSetMap = new HashMap<>();
		if (fillerhazard.getFiller() != null) {

			Set<Integer> fillerIds = new HashSet<Integer>();
			fillerIds.add(fillerhazard.getFiller().getId());
			objectReferencedSetMap.put("fillerIds", fillerIds);
		}
		if (fillerhazard.getHazard() != null) {

			Set<Integer> hazardIds = new HashSet<Integer>();
			hazardIds.add(fillerhazard.getHazard().getId());
			objectReferencedSetMap.put("hazardIds", hazardIds);
		}

		return objectReferencedSetMap;
	}

	public Map<String, ?> loadFillerhazardClassReferencedSet(Fillerhazard fillerhazard) {
		HashMap<String, Object> classReferencedSetMap = new HashMap<>();
		classReferencedSetMap.put("fillers", fillerDAO.findAllFillers());
		classReferencedSetMap.put("hazards", hazardDAO.findAllHazards());

		return classReferencedSetMap;
	}

	public boolean isEquals(Fillerhazard fillerhazard, Object obj) {
		if (obj == fillerhazard)
			return true;
		if (!(obj instanceof Fillerhazard))
			return false;
		Fillerhazard comparedFillerhazard = (Fillerhazard) obj;
		if (!CheckPropertyEqual(fillerhazard.getFiller().getId(), comparedFillerhazard.getFiller().getId())) {
			return false;
		}
		if (!CheckPropertyEqual(fillerhazard.getHazard().getId(), comparedFillerhazard.getHazard().getId())) {
			return false;
		}
		if (!CheckPropertyEqual(fillerhazard.getDegree(), comparedFillerhazard.getDegree())) {
			return false;
		}
		return true;
	}

	public static <T> boolean CheckPropertyEqual(T originProperty, T comparedProperty) {
		// 基本类型经过参数传递后会自动装箱
		String[] className = originProperty.getClass().getName().split("\\.");
		if (className[0].equals("java") && className[1].equals("math")) {
			return ((Comparable) originProperty).compareTo(comparedProperty) == 0 ? true : false;
		} else {
			return originProperty.equals(comparedProperty);
		}
	}
}

